<?php

namespace app\api\model\shop;


use addons\epay\library\Service;
use app\api\model\Pay;
use app\api\model\Qrcode;

use app\api\model\UserConsumeLog;
use app\common\model\User;
use app\shopapi\model\ShopGoods;
use think\Db;
use think\Model;
use traits\model\SoftDelete;
use think\Cache;
use Yansongda\Pay\Exceptions\GatewayException;

class ShopOrder extends Model
{
    use SoftDelete;
    // 表名
    protected $name = 'shop_order';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'integer';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';

    // 追加属性
    protected $append = [
        'createtime_text',
        'pay_time_text',
    ];

    // 订单待付款
    const ORDER_CREATE = 0;

    // 订单已支付
    //const ORDER_PAY = 1;

    // 订单待使用
    const ORDER_VERIFY = 2;

    // 订单已完成
    const ORDER_COMPLETE = 3;

    // 订单退款
    const ORDER_REFUND = 4;
    // 订单已关闭
    const ORDER_CLOSE = -1;
    /**
     * 基础订单状态(不同类型的订单可以不使用这些状态，但是不能冲突)
     * @var unknown
     */
    public $order_status = [
        self::ORDER_CREATE => [
            'status' => self::ORDER_CREATE,
            'name' => '待支付',
        ],
        self::ORDER_VERIFY => [
            'status' => self::ORDER_VERIFY,
            'name' => '待使用',
        ],
        self::ORDER_COMPLETE => [
            'status' => self::ORDER_COMPLETE,
            'name' => '已完成',
        ],
        self::ORDER_CLOSE => [
            'status' => self::ORDER_CLOSE,
            'name' => '已关闭',
        ],
        self::ORDER_REFUND => [
            'status' => self::ORDER_REFUND,
            'name' => '退款',
        ],
    ];


    public function getCreatetimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['createtime']) ? $data['createtime'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }

    public function getPayTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['pay_time']) ? $data['pay_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }

    //团购订单列表
    public function lists($condition)
    {

        $lists = ShopOrder::alias('so')
            ->join('shop s', 'so.shop_id=s.shop_id')
            ->where($condition)
            ->field('so.*,s.shop_name')
            ->order('so.createtime desc')
            ->paginate(10, false, ['query' => request()->get()]);

        return $lists;
    }

    //团购订单详情
    public function userdetail($params)
    {
        $order_id = $params['order_id'];
        $user_id = $params['user_id'];
        $weapp = $params['weapp'] ?? "";
        $lng = $params['lng'] ?? "";
        $lat = $params['lat'] ?? "";
        if (empty($order_id)){
            throw new \Exception('缺少参数订单id');
        }

        $order_info = ShopOrder::where(['user_id'=>$user_id,'order_id'=>$order_id])->find();

        if (empty($order_info)){
            throw new \Exception('不是该用户订单');
        }

        $code_result = $this->orderQrcode($order_info,$weapp);
        $order_info['verify_qrcode'] = $code_result['data'];

        $shop_model = new Shop();
        $shop_info = $shop_model->getShopInfo(['shop_id'=>$order_info['shop_id']],$lat,$lng);
        $order_info['shop_info'] = $shop_info;

        $goods_info = $shop_model->orderGoodsDetail($order_info['goods_id']);
        $order_info['goods_info'] = $goods_info;
        return $order_info;
    }

    //退款
    public function refund($params)
    {
        $order_info = ShopOrder::where(['user_id'=>$params['user_id'],'order_id'=>$params['order_id']])->find();
        if (empty($order_info)){
            throw new \Exception('订单信息不存在');
        }

        Db::startTrans();

        try {
            $order_info->setAttr('order_status',self::ORDER_REFUND);
            $order_info->order_status_name = $this->order_status[ self::ORDER_REFUND ][ "name" ];
            $order_info->is_refund = 1;
            //$order_info->refund = 1;
            $order_info->refund_no = $this->createRefundNo($order_info->order_id);
            $order_info->closetime = time();

            $shop = Shop::get($order_info->shop_id);

            //执行原路退款
            $pay_model = new \app\shopapi\model\lakala\Pay();

            $refund_res = $pay_model->refund($order_info->lakala_order_no, $order_info->refund_no,$order_info->pay_price,$order_info->pay_seq_no,$shop->member_no);

            if ($refund_res['code']==0){
                throw new \Exception($refund_res['msg']);
            }
            /*$refund_res = $this->refundPrice($order_info->lakala_order_no, $order_info->refund_no,$order_info->pay_price,$order_info->pay_seq_no,$shop['member_no']);

            if ($refund_res['code']==0){
                throw new \Exception($refund_res['msg']);
            }*/
            $res = $order_info->save();

            //修改消费记录状态为退款
            $consume_log = UserConsumeLog::update(['is_refund'=>1,'order_status_name'=>'收益扣回'],['order_no'=>$order_info->order_no]);
            Db::commit();
            return $res;
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw new \Exception($e->getMessage());
        }

    }

    //执行退款
    public function refundPrice($order_no,$out_request_no,$refund_amount,$pay_seq_no,$member_no)
    {
        $pay_model = new \app\shopapi\model\lakala\Pay();

        $res = $pay_model->refund($order_no,$out_request_no,$refund_amount,$pay_seq_no,$member_no);

        return $res;
        /*$pay_model = new Pay();

        $res = $pay_model->refund($order_info->order_no,$order_info->pay_price,$order_info->shop_id);

        if ($res['code']==0){
            return [
                'code'=>0,
                'msg'=>$res['msg']
            ];
        } else {
            return [
                'code'=>1,
                //'data'=>$res['data'],
                'msg'=>'success'
            ];
        }*/
    }

    /**
     * 创建退款流水号
     */
    public function createRefundNo($unique)
    {
        $no = createno('refund_no', '', $unique);
        return $no;
    }
    /**
     * 订单生成码
     * @param $order_info
     * @return array
     */
    public function orderQrcode($order_info,$app_type)
    {
        $data = [
            'app_type' => $app_type, // all为全部
            'type' => 'get', // 类型 create创建 get获取
            'data' => [
                "code" => $order_info['verify_code']
            ],
            'page' => '/otherpages/verification/detail/detail',
            'qrcode_path' => 'upload/qrcode/' . 'virtualgoods',
            'qrcode_name' =>  'virtualgoods_' . $order_info['verify_code'],
        ];
        $qrcode_model = new Qrcode();
        $res = $qrcode_model->createQrcode($data);

        return $res;
    }

    public static function getDetail($order_no, $user_id)
    {
        return self::where('order_no', $order_no)->where('user_id', $user_id)->find();
    }

    /**
     * @ 支付
     * @param string $orderid
     * @param int    $user_id
     * @param string $paytype
     * @param string $method
     * @param string $openid
     * @param string $notifyurl
     * @param string $returnurl
     * @return \addons\epay\library\Collection|\addons\epay\library\RedirectResponse|\addons\epay\library\Response|null
     * @throws \Exception
     */
    public static function pay($orderid, $user_id, $paytype, $method = 'web', $openid = '', $notifyurl = null, $returnurl = null)
    {
        $request = \think\Request::instance();
        $order = self::getDetail($orderid, $user_id);
        if (!$order) {
            throw new \Exception('订单不存在！');
        }
        if ($order->pay_status) {
            throw new \Exception('订单已支付！');
        }
        if ($order->order_status==-1) {
            throw new \Exception('订单已失效！');
        }
        //支付金额为0，无需支付
        if ($order->order_price == 0) {
            throw new \Exception('无需支付！');
        }
        $order_no = $order->order_no;
        // 启动事务
        Db::startTrans();
        try {
            //支付方式变更
            if (($order['method'] && $order['pay_type'] == $paytype && $order['method'] != $method)) {
                $order_no = date("Ymdhis") . sprintf("%08d", $user_id) . mt_rand(1000, 9999);

            }
            //更新支付类型和方法
            $order->save(['pay_type' => $paytype, 'method' => $method]);
            //提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw new \Exception($e->getMessage());
        }
        $response = null;
        $epay = get_addon_info('epay');

        if ($epay && $epay['state']) {

            $notifyurl = $notifyurl ? $notifyurl : $request->root(true) . '/api/shop/shoporder/epay/type/notify/paytype/' . $paytype;
            $returnurl = $returnurl ? $returnurl : $request->root(true) . '/api/shop/shoporder/epay/type/notify/paytype/' . $paytype . '/order_no/' . $order_no;

            //保证取出的金额一致，不一致将导致订单重复错误
            $amount = sprintf("%.2f", $order->pay_status);

            $params = [
                'amount'    => $amount,
                'orderid'   => $order_no,
                'type'      => $paytype,
                'title'     => "支付{$amount}元",
                'notifyurl' => $notifyurl,
                'returnurl' => $returnurl,
                'method'    => $method,
                'openid'    => $openid
            ];
            try {
                $response = Service::submitOrder($params);
            } catch (GatewayException $e) {
                throw new \Exception(config('app_debug') ? $e->getMessage() : "支付失败，请稍后重试");
            }
        } else {
            throw new \Exception("请在后台安装配置微信支付宝整合插件");
        }
        return $response;
    }

    //线下支付
    public function offlinepay($order_no,$user_id)
    {
        $order = self::getDetail($order_no, $user_id);
        $res = $this->orderPay($order_no,$order['order_price']);

        return $res;
    }

    //支付订单
    public  function orderPay($order_sn, $payamount, $trans_type,$pay_time,$pay_seq_no,$split_seq_no)
    {
        $order = self::where('lakala_order_no', $order_sn)->find();
        if (!$order || $order->pay_status == 1) {
            return false;
        }

        if ($payamount != $order->order_price) {
            \think\Log::write("[shop][pay][{$order_sn}][订单支付金额不一致]");
            return false;
        }

        $shop = Shop::get($order->shop_id);

        Db::startTrans();

        try {
            $order->pay_status = 1;
            $order->setAttr('order_status',self::ORDER_VERIFY);
            $order->order_status_name = $this->order_status[ self::ORDER_VERIFY ][ "name" ];
            $order->pay_seq_no = $pay_seq_no;
            $order->split_seq_no = $split_seq_no;
            $order->pay_price = $payamount;
            $order->pay_time = strtotime($pay_time);
            $order->pay_type = $trans_type;
            //$order->method = !$order->method ? 'system' : $order->method;
            $order->verify_code = $this->getCode($order->order_id);
            if ($order->may_use_time_type==1){
                $order->start_may_use_time = time();
                $order->end_may_use_time =$order->may_use_time_day*86400;
            }
            $res = $order->save();
            //商品增加销量/销售额
            ShopGoods::where(['goods_id'=>$order->goods_id])->setInc('sale',1);
            ShopGoods::where(['goods_id'=>$order->goods_id])->setInc('sale_price',$order->pay_price);

            //增加消费记录
            $consume_log_model = new UserConsumeLog();
            $consume_log_data = [
                'user_id'=>$order->user_id,
                'title'=>$order->goods_name,
                'shop_id'=>$order->shop_id,
                'shop_name'=>$shop->shop_name,
                'image'=>$order->goods_img,
                'order_no'=>$order->order_no,
                'pay_time'=>$order->pay_time,
                'pay_price'=>$order->pay_price,
                'consume_type'=>3,
                'goods_id'=>$order->goods_id,
                'commission'=>$order->rebate,
                'total_commission'=>$order->rebate,
                'order_status_name'=>'已付款'
            ];

            $consume_log_model->save($consume_log_data);
            User::update(['is_buy'=>1],['id'=>$order->user_id]);

            $user_model = new User();
            $user_model->upgrade($order->user_id);

            //User::upgrade($order->user_id);
            $consume_log_model->save($consume_log_data);

            //收益
            //UserConsumeLog::lockMemberConsumeCalculate($order->user_id,$consume_log_model->total_commission,$consume_log_model->consume_id,1);
            //UserConsumeLog::recommendShopConsumeCalculate($order->user_id,$order->shop_id,$consume_log_model->total_commission,$consume_log_model->consume_id,1);
            //发放收益
            //UserConsumeLog::sendCommission($order->order_no);

            Db::commit();
            return $res;
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw new \Exception($e->getMessage().$e->getLine());
            //return false;
        }
    }

    public function getCode($unique)
    {
        $code = createno('verify_no', '', $unique);
        //todo  生成编号
        return $code;
//		return random_keys(12);
    }
}